#ifndef     __DECODE_H
#define     __DECODE_H

#include <stdint.h>
#include <type_traits>

namespace utils {

constexpr uint32_t DecodeFail = static_cast<uint32_t>(-1);

inline uint8_t decode_uint8(const uint8_t *buf) {
    return buf[0];
}

inline uint16_t decode_uint16(const uint8_t *buf) {
    return (buf[0] << 8) + buf[1];
}

inline uint32_t decode_uint32(const uint8_t *buf) {
    return (buf[0] << 24) +
        (buf[1] << 16) +
        (buf[2] << 8) +
        buf[3];
}

template <typename T, uint32_t Size = sizeof (T)>
inline std::enable_if_t<Size == 1, T>
decode_any(const uint8_t *buf) {
    return static_cast<T>(decode_uint8(buf));
}

template <typename T, uint32_t Size = sizeof (T)>
inline std::enable_if_t<Size == 2, T>
decode_any(const uint8_t *buf) {
    return static_cast<T>(decode_uint16(buf));
}

template <typename T, uint32_t Size = sizeof (T)>
inline std::enable_if_t<Size == 4, T>
decode_any(const uint8_t *buf) {
    return static_cast<T>(decode_uint32(buf));
}


}


#endif
